package com.easypan.service.impl;

//import com.easypan.component.RedisComponent;
//import com.easypan.entity.config.AppConfig;
//import com.easypan.entity.config.TencentEmailConfig;
import com.easypan.component.RedisComponent;
import com.easypan.entity.config.AppConfig;
import com.easypan.entity.constants.Constants;
import com.easypan.entity.dto.SysSettingsDto;
import com.easypan.entity.enums.PageSize;
import com.easypan.entity.po.EmailCode;
import com.easypan.entity.po.UserInfo;
import com.easypan.entity.query.EmailCodeQuery;
import com.easypan.entity.query.SimplePage;
import com.easypan.entity.query.UserInfoQuery;
import com.easypan.entity.vo.PaginationResultVO;
import com.easypan.exception.BusinessException;
import com.easypan.mappers.EmailCodeMapper;
import com.easypan.mappers.UserInfoMapper;
import com.easypan.service.EmailCodeService;
import com.easypan.utils.EmailTools;
import com.easypan.utils.StringTools;
//import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;


/**
 * 邮箱验证码 业务接口实现
 */
@Service("emailCodeService")
//@Slf4j
public class EmailCodeServiceImpl implements EmailCodeService {

    private static final Logger logger = LoggerFactory.getLogger(EmailCodeServiceImpl.class);

    @Resource
    private EmailCodeMapper<EmailCode, EmailCodeQuery> emailCodeMapper;

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private AppConfig appConfig;

    @Resource
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

    @Resource
    private RedisComponent redisComponent;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

//    @Resource
//    private TencentEmailConfig tencentEmailConfig;


//    /**
//     * 发送邮件验证码2
//     *
//     * @param toEmail
//     * @param code
//     */
//    private void sendEmailCode(String toEmail, String code) {
//        // 基于私人邮箱发送
///*
//        try {
//            MimeMessage message = javaMailSender.createMimeMessage();
//
//            MimeMessageHelper helper = new MimeMessageHelper(message, true);
//            //邮件发件人
//            helper.setFrom(appConfig.getSendUserName());
//            //邮件收件人 1或多个
//            helper.setTo(toEmail);
//
//            // 邮件的格式
//            SysSettingsDto sysSettingsDto = redisComponent.getSysSettingsDto();
//
//            //邮件主题
//            helper.setSubject(sysSettingsDto.getRegisterEmailTitle());
//            //邮件内容
//            helper.setText(String.format(sysSettingsDto.getRegisterEmailContent(), code));
//            //邮件发送时间
//            helper.setSentDate(new Date());
//            javaMailSender.send(message);
//
//        } catch (Exception e) {
//            logger.error("邮件发送失败", e);
//            throw new BusinessException("邮件发送失败");
//        }
//*/
//
//
//        // 腾讯云邮件推送:
//        // this.sendEmail(toEmail, code);
//    }


    /**
     * 发送邮件验证码
     *
     * @param email
     * @param type
     */
    @Override
    @Transactional(rollbackFor = Exception.class)//事务注解
    public void sendEmailCode(String email, Integer type){
        //如果是注册，校验邮箱是否已存在
        if (type == Constants.ZERO) {
            UserInfo userInfo = userInfoMapper.selectByEmail(email);
            if (null != userInfo) {
                throw new BusinessException("邮箱已存在");
            }
        }

        // 生成长度为5的随机数
        String code = StringTools.getRandomNumber(Constants.LENGTH_5);
        //发送邮件验证码
         sendEmailCode(email,code);
        //this.sendEmail(email, code);
        //log.info("发送验证码成功 " + email + " : " + code);

        // 将之前的验证码置为失效
        emailCodeMapper.disableEmailCode(email);
        EmailCode emailCode = new EmailCode();
        emailCode.setCode(code);
        emailCode.setEmail(email);
        emailCode.setStatus(Constants.ZERO);
        emailCode.setCreateTime(new Date());
        emailCodeMapper.insert(emailCode);

        // 将验证码保存到redis    120s有效期
        //stringRedisTemplate.opsForValue().set(Constants.REDIS_KEY_EMAIL_CODE + email, code, 120, TimeUnit.SECONDS);
    }
    private void sendEmailCode(String toEmail, String code){
        try {
            // 基于私人邮箱发送
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //邮件发件人
            helper.setFrom(appConfig.getSendUserName());
            //邮件收件人 1或多个
            helper.setTo(toEmail);
            // 邮件的格式
            SysSettingsDto sysSettingsDto = redisComponent.getSysSettingsDto();
            //邮件主题
            helper.setSubject(sysSettingsDto.getRegisterEmailTitle());
            //邮件内容
            helper.setText(String.format(sysSettingsDto.getRegisterEmailContent(), code));
            //邮件发送时间
            helper.setSentDate(new Date());
            javaMailSender.send(message);
        } catch (Exception e) {
            logger.error("邮件发送失败", e);
            throw new BusinessException("邮件发送失败");
        }
    }

    /**
     * 检查验证码
     *
     * @param email
     * @param code
     */
    @Override
    public void checkCode(String email, String code) {
        EmailCode emailCode = emailCodeMapper.selectByEmailAndCode(email, code);
        if (null == emailCode) {
            throw new BusinessException("邮箱验证码不正确");
        }
        if (emailCode.getStatus() == 1 || System.currentTimeMillis() - emailCode.getCreateTime().getTime() > Constants.LENGTH_15 * 1000 * 60) {
            throw new BusinessException("邮箱验证码已失效");
        }
        emailCodeMapper.disableEmailCode(email);

        // 邮箱验证码存在redis的验证方式
//        String redisCode = stringRedisTemplate.opsForValue().get(Constants.REDIS_KEY_EMAIL_CODE + email);
//        if (redisCode == null) {
//            throw new BusinessException("邮箱验证码已失效~");
//        }
//        if (!redisCode.equals(code)) {
//            throw new BusinessException("邮箱验证码不正确~");
//        }
        // 校验正确后删除redis里的邮箱验证码
        //stringRedisTemplate.delete(Constants.REDIS_KEY_EMAIL_CODE + email);
    }

//    /**
//     * 腾讯云发送邮件
//     *
//     * @param toAddress
//     * @param code
//     */
//    public void sendEmail(String toAddress, String code) {
//        String SMTP_HOST = tencentEmailConfig.getSMTP_HOST();
//        String SMTP_PORT = tencentEmailConfig.getSMTP_PORT();
//        String fromAddress = tencentEmailConfig.getFromAddress();
//        String password = tencentEmailConfig.getPassword();
//        String fromName = tencentEmailConfig.getFromName();
//        // String title = tencentEmailConfig.getTitle();
//        // String emailContent = tencentEmailConfig.getEmailContent();
//
//        SysSettingsDto sysSettingsDto = redisComponent.getSysSettingsDto();
//        String title = sysSettingsDto.getRegisterEmailTitle();
//        String emailContent = sysSettingsDto.getRegisterEmailContent();
//
//        // 配置发送邮件的环境属性
//        final Properties props = new Properties();
//        // 表示SMTP发送邮件，需要进行身份验证
//        props.put("mail.smtp.auth", "true");
//        props.put("mail.smtp.host", SMTP_HOST);
//        // 如果使用ssl，则去掉使用25端口的配置，进行如下配置,
//        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
//        props.put("mail.smtp.socketFactory.port", SMTP_PORT);
//        props.put("mail.smtp.port", SMTP_PORT);
//        // 发件人的账号，填写控制台配置的发信地址,比如xxx@xxx.com
//        props.put("mail.user", fromAddress);
//        // 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)
//        props.put("mail.password", password);
//        props.setProperty("mail.smtp.socketFactory.fallback", "false");
//        props.put("mail.smtp.ssl.enable", "true");
//        //props.put("mail.smtp.starttls.enable","true");
//        // 构建授权信息，用于进行SMTP进行身份验证
//        Authenticator authenticator = new Authenticator() {
//            @Override
//            protected PasswordAuthentication getPasswordAuthentication() {
//                // 用户名、密码
//                String userName = props.getProperty("mail.user");
//                String password = props.getProperty("mail.password");
//                return new PasswordAuthentication(userName, password);
//            }
//        };
//        // 使用环境属性和授权信息，创建邮件会话
//        Session mailSession = Session.getInstance(props, authenticator);
////        mailSession.setDebug(true);
//        //UUID uuid = UUID.randomUUID();
//        //final String messageIDValue = "<" + uuid.toString() + ">";
//        // 创建邮件消息
//        MimeMessage message = new MimeMessage(mailSession) {
//            //@Override
//            //protected void updateMessageID() throws MessagingException {
//            //设置自定义Message-ID值
//            //setHeader("Message-ID", messageIDValue);
//            //}
//        };
//        try {
//            // 设置发件人邮件地址和名称。填写控制台配置的发信地址,比如xxx@xxx.com。和上面的mail.user保持一致。名称用户可以自定义填写。
//            InternetAddress from = new InternetAddress(fromAddress, fromName);
//            message.setFrom(from);
//            //可选。设置回信地址
////            Address[] a = new Address[1];
////            a[0] = new InternetAddress("***");
////            message.setReplyTo(a);
//            // 设置收件人邮件地址，比如yyy@yyy.com
//            InternetAddress to = new InternetAddress(toAddress);
//            message.setRecipient(MimeMessage.RecipientType.TO, to);
//            //如果同时发给多人，才将上面两行替换为如下（因为部分收信系统的一些限制，尽量每次投递给一个人；同时我们限制单次允许发送的人数是50人）：
//            //InternetAddress[] adds = new InternetAddress[2];
//            //adds[0] = new InternetAddress("xxx@xxx.com");
//            //adds[1] = new InternetAddress("xxx@xxx.com");
//            //message.setRecipients(Message.RecipientType.TO, adds);
//
//
//            // 设置邮件标题
//            message.setSubject(title);
//            message.setHeader("Content-Transfer-Encoding", "base64");
//            // 设置邮件的内容体 type: text/plain（纯文本）text/html（HTML 文档）
//            String content = emailContent.replace("{code}", code);
//            message.setContent(content, "text/html;charset=UTF-8");
//            //发送邮件
//            Transport.send(message);
//        } catch (MessagingException | UnsupportedEncodingException e) {
//            String err = e.getMessage();
//            err = new String(err.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//            System.out.println(err);
//        }
//    }
}